﻿using Microsoft.AspNetCore.Cryptography.KeyDerivation;
using System.Security.Cryptography;
using System.Text;

namespace BuddHa.Common.CryptoOpex
{
    public class CryptoHelper
    {
        /// <summary>
        /// MD5加密
        /// </summary>
        /// <param name="content">加密内容</param>
        /// <returns></returns>
        public static string MD5Encrypt(string content)
        {
            return MD5Encrypt(content, Encoding.UTF8);
        }

        /// <summary>
        /// MD5密码
        /// </summary>
        /// <param name="content">加密内容</param>
        /// <param name="encoding">编码</param>
        /// <returns></returns>
        public static string MD5Encrypt(string content, Encoding encoding)
        {
            var md5 = MD5.Create();
            var dataByte = md5.ComputeHash(encoding.GetBytes(content));

            return BitConverter.ToString(dataByte).Replace("-", "");
        }

        /// <summary>
        /// 通过Base64加密字符串
        /// </summary>
        public static string Base64Encode(string content)
        {
            return Convert.ToBase64String(Encoding.UTF8.GetBytes(content));
        }

        /// <summary>
        /// 通过Base64解密字符串
        /// </summary>
        public static string Base64Decode(string content)
        {
            return Encoding.UTF8.GetString(Convert.FromBase64String(content));
        }

        /// <summary>
        /// SHA256 签名计算
        /// </summary>
        /// <param name="srcString">The string to be encrypted</param>
        /// <returns></returns>
        public static string GetSHA256(string content)
        {
            return Convert.ToHexString(System.Security.Cryptography.SHA256.HashData(Encoding.UTF8.GetBytes(content)));
        }

        /// <summary>
        /// SHA256加密
        /// </summary>
        /// <param name="data">数据</param>
        /// <returns></returns>
        public static string SHA256(string content)
        {
            var byteData = Encoding.UTF8.GetBytes(content);
            var result = System.Security.Cryptography.SHA256.HashData(byteData);
            return BitConverter.ToString(result).Replace("-", "").ToLower();
        }


        /// <summary>
        /// SHA512 签名计算
        /// </summary>
        /// <param name="srcString">The string to be encrypted</param>
        /// <returns></returns>
        public static string GetSHA512(string content)
        {
            return Convert.ToHexString(SHA512.HashData(Encoding.UTF8.GetBytes(content)));
        }

        /// <summary>
        /// HMACSHA1
        /// </summary>
        /// <param name="content">数据</param>
        /// <param name="key">密钥</param>
        /// <returns></returns>
        public static string HMACSHA1Encrypt(string content, string key)
        {
            var byteData = Encoding.UTF8.GetBytes(content);
            var byteKey = Encoding.UTF8.GetBytes(key);
            var hmacsha1 = new HMACSHA1(byteKey);
            var result = hmacsha1.ComputeHash(byteData);
            return Convert.ToBase64String(result);
        }

        /// <summary>
        /// SHA1加密
        /// </summary>
        /// <param name="content">加密内容</param>
        /// <returns></returns>

        public static string SHA1Encrypt(string content)
        {
            var byteData = Encoding.UTF8.GetBytes(content);
            var result = SHA1.HashData(byteData);
            return BitConverter.ToString(result).Replace("-", "").ToLower();
        }

        /// <summary>
        /// PBKDF2算法通过多吃hash来对密码进行加密。原理是通过password和salt进行hash，然后将结果作为salt在与password进行hash，多次重复此过程，生成最终的密文。此过程可能达到上千次，逆向破解的难度太大，破解一个密码的时间可能需要几百年，所以PBKDF2算法是安全的。
        /// </summary>
        /// <param name="password">待加密密码</param>
        /// <param name="salt">随机盐</param>
        /// <param name="iterations">迭代次数</param>
        /// <param name="numBytes">衍生索引键的位元组，所需的长度</param>
        /// <returns></returns>
        public static string PbKdf2Encode(String password, String salt, int iterations = 1000, int numBytes = 32)
        {
             return Convert.ToBase64String(KeyDerivation.Pbkdf2(password, Encoding.UTF8.GetBytes(salt), KeyDerivationPrf.HMACSHA256, iterations, numBytes));
        }

    }
}
